home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Science / µSim 1.0b5 folder / Libs / UtilsCommon.c < prev    next >
Encoding:
Text File  |  1994-10-04  |  37.6 KB  |  1,453 lines  |  [TEXT/MMCC]

  1. /*
  2. Copyright © 1993,1994 by Fabrizio Oddone
  3. ••• ••• ••• ••• ••• ••• ••• ••• ••• •••
  4. This source code is distributed as freeware: you can copy, exchange, modify this
  5. code as you wish. You may include this code in any kind of application: freeware,
  6. shareware, or commercial, provided that full credits are given.
  7. You may not sell or distribute this code for profit.
  8. */
  9.  
  10. //#pragma load "MacDump"
  11.  
  12. #include    "Independents.h"
  13.  
  14. #if !(defined(powerc) || defined (__powerc)) || defined(FabSystem7orlater)
  15.  
  16. #if    !defined(FabNoSegmentDirectives)
  17. #pragma segment __%Main
  18. #endif
  19.  
  20. static AEEventHandlerUPP    gmyOAPP_UPP, gmyODOC_UPP, gmyPDOC_UPP, gmyQUIT_UPP;
  21.  
  22. #if defined(powerc) || defined (__powerc)
  23.  
  24. pascal StringPtr     PLstrcpy(StringPtr str1, ConstStr255Param str2)
  25. {
  26. BlockMoveData(str2, str1, Length(str2) + 1);
  27. return str1;
  28. }
  29.  
  30. pascal StringPtr     PLstrncpy(StringPtr str1, ConstStr255Param str2, short num)
  31. {
  32. BlockMoveData(str2, str1, 1 + MIN(Length(str2), num));
  33. return str1;
  34. }
  35.  
  36. pascal StringPtr    PLstrcat(StringPtr str1, ConstStr255Param str2)
  37. {
  38. BlockMoveData(str2 + 1, str1 + Length(str1) + 1, Length(str2));
  39. Length(str1) += Length(str2);
  40. return str1;
  41. }
  42.  
  43. void MyZeroBuffer(long *p, long s)
  44. {
  45. for ( ; s-- >= 0; *p++ = 0L);
  46. }
  47.  
  48. void MyFillBuffer(long *p, long s, long filler)
  49. {
  50. for ( ; s-- >= 0; *p++ = filler);
  51. }
  52.  
  53. long mySwap(long s)
  54. {
  55. long    t;
  56.  
  57. t = s >> 16;
  58. *(short *)&t = (short) s;
  59. return t;
  60. }
  61.  
  62. #endif
  63.  
  64. /* AddSTRRes2Doc: adds the standard 'STR ' resource
  65. to a newly saved document */
  66.  
  67. OSErr AddSTRRes2Doc(FSSpec *theDoc, OSType myFcrea, OSType myFtype, short STRid, ScriptCode lScript)
  68. {
  69. register Handle    msgString;
  70. register short    fRefn;
  71. register OSErr    err;
  72.  
  73. DetachResource(msgString = (Handle)GetString(STRid));
  74. FSpCreateResFile(theDoc, myFcrea, myFtype, lScript);
  75. if ((err = ResError()) == noErr)
  76.     if ((fRefn = FSpOpenResFile(theDoc, fsRdWrPerm)) == -1)
  77.         err = ResError();
  78.     else {
  79.         AddResource(msgString, 'STR ', STRid, "\p");
  80.         if ((err = ResError()) == noErr) {
  81.             SetResAttrs(msgString, GetResAttrs(msgString) | resPurgeable);
  82.             err = ResError();
  83.             }
  84.         else
  85.             DisposHandle(msgString);
  86.         CloseResFile(fRefn);
  87.         }
  88. return err;
  89. }
  90.  
  91. /* AddSTRHand2Doc: adds the standard 'STR ' resource
  92. to a newly saved document */
  93.  
  94. OSErr AddSTRHand2Doc(FSSpec *theDoc, OSType myFcrea, OSType myFtype, StringHandle msgString, ScriptCode lScript)
  95. {
  96. register short    fRefn;
  97. register OSErr    err;
  98.  
  99. FSpCreateResFile(theDoc, myFcrea, myFtype, lScript);
  100. if ((err = ResError()) == noErr)
  101.     if ((fRefn = FSpOpenResFile(theDoc, fsRdWrPerm)) == -1)
  102.         err = ResError();
  103.     else {
  104.         AddResource((Handle)msgString, 'STR ', kSTR_ApplicationName, "\p");
  105.         if ((err = ResError()) == noErr) {
  106.             SetResAttrs((Handle)msgString, GetResAttrs((Handle)msgString) | resPurgeable);
  107.             err = ResError();
  108.             }
  109.         else
  110.             DisposHandle((Handle)msgString);
  111.         CloseResFile(fRefn);
  112.         }
  113. return err;
  114. }
  115.  
  116. OSErr AddRes2Doc(FSSpec *theDoc, Handle thisHandle, ResType rType, short rID)
  117. {
  118. register Handle    existHandle;
  119. register short    fRefn;
  120. register OSErr    err;
  121.  
  122. if ((fRefn = FSpOpenResFile(theDoc, fsRdWrPerm)) == -1)
  123.     err = ResError();
  124. else {
  125. //    if (noErr == (err = HandToHand(&thisHandle)))
  126.     SetResLoad(false);
  127.     existHandle = Get1Resource(rType, rID);
  128.     SetResLoad(true);
  129.     if (existHandle) {
  130.         RmveResource(existHandle);
  131.         DisposHandle(existHandle);
  132.         }
  133.     AddResource(thisHandle, rType, rID, "\p");
  134.     if ((err = ResError()) == noErr) {
  135.         SetResAttrs(thisHandle, GetResAttrs(thisHandle) | resPurgeable);
  136.         err = ResError();
  137.         }
  138.     CloseResFile(fRefn);
  139.     }
  140. return err;
  141. }
  142.  
  143. /* SendmyAE: we send an Apple Event with the specified ID to ourselves */
  144.  
  145. void SendmyAE(AEEventClass myclass, AEEventID myAEvtID, AEIdleProcPtr IdleFunct, AESendMode theMode)
  146. {
  147. AEIdleUPP    IdleFunctUPP = NewAEIdleProc(IdleFunct);
  148. AppleEvent    myAEvent;
  149. AppleEvent    myAEReply;
  150. AEAddressDesc    targetAddress;
  151. ProcessSerialNumber myPSN = { 0, kCurrentProcess };
  152. register OSErr    err;
  153.  
  154. if ((err = AECreateDesc(typeProcessSerialNumber, (Ptr)&myPSN, sizeof(ProcessSerialNumber),
  155.     &targetAddress)) == noErr) {
  156.     if ((err = AECreateAppleEvent(myclass, myAEvtID, &targetAddress,
  157.         kAutoGenerateReturnID, kAnyTransactionID, &myAEvent)) == noErr) {
  158.         err = AESend(&myAEvent, &myAEReply, theMode,
  159.             kAENormalPriority, kNoTimeOut, IdleFunctUPP, 0L);
  160.         (void)AEDisposeDesc(&myAEvent);
  161.         }
  162.     (void)AEDisposeDesc(&targetAddress);
  163.     }
  164. if (IdleFunctUPP)
  165.     DisposeRoutineDescriptor(IdleFunctUPP);
  166. }
  167.  
  168. /* SendmyAEPShort: we send an Apple Event with the specified ID to ourselves */
  169.  
  170. void SendmyAEPShort(AEEventClass myclass, AEEventID myAEvtID, AEIdleProcPtr IdleFunct, AESendMode theMode, short theAlert)
  171. {
  172. AEIdleUPP    IdleFunctUPP = NewAEIdleProc(IdleFunct);
  173. AppleEvent    myAEvent;
  174. AppleEvent    myAEReply;
  175. AEAddressDesc    targetAddress;
  176. ProcessSerialNumber myPSN = { 0, kCurrentProcess };
  177. register OSErr    err;
  178.  
  179. if ((err = AECreateDesc(typeProcessSerialNumber, (Ptr)&myPSN, sizeof(ProcessSerialNumber),
  180.     &targetAddress)) == noErr) {
  181.     if ((err = AECreateAppleEvent(myclass, myAEvtID, &targetAddress,
  182.         kAutoGenerateReturnID, kAnyTransactionID, &myAEvent)) == noErr) {
  183.  
  184.         if ((err = AEPutParamPtr(&myAEvent, keyDirectObject, typeShortInteger, (Ptr)&theAlert, sizeof(theAlert))) == noErr)
  185.             err = AESend(&myAEvent, &myAEReply, theMode,
  186.                 kAENormalPriority, kNoTimeOut, IdleFunctUPP, 0L);
  187.         (void)AEDisposeDesc(&myAEvent);
  188.         }
  189.     (void)AEDisposeDesc(&targetAddress);
  190.     }
  191. if (IdleFunctUPP)
  192.     DisposeRoutineDescriptor(IdleFunctUPP);
  193. }
  194.  
  195. /* ZoomRectToRect: draws zooming gray rectangles from startingRect to endingRect
  196. in the current port; numofDivs is the density of rectangles in the interval */
  197.  
  198. void ZoomRectToRect(RectPtr startingRect, RectPtr endingRect, short numofDivs)
  199. {
  200. PenState    curPen;
  201. Rect    trailingRect = { 0, 0, 0, 0 };
  202. Rect    tempRect;
  203. Handle    rectStorH;
  204. short    mtop, mleft, mbottom, mright;
  205. register long    ttopleft, tbotright;
  206. register short *spntr;
  207. register long *lpntr;
  208. register short    i, j, tsh;
  209.  
  210. if (numofDivs < (CHAR_BIT * sizeof(short))) {
  211.     if (rectStorH = NewHandleGeneral(numofDivs * sizeof(Rect))) {
  212.         GetPenState(&curPen);
  213.         PenPat(&qd.gray);
  214.         PenMode(patXor);
  215.         mtop = endingRect->top - startingRect->top;
  216.         mleft = endingRect->left - startingRect->left;
  217.         mbottom = endingRect->bottom - startingRect->bottom;
  218.         mright = endingRect->right - startingRect->right;
  219.         spntr = (short *)*rectStorH;
  220.         for (i = 1; i <= numofDivs; i++) {
  221.             *spntr++ = mtop >>= 1;
  222.             *spntr++ = mleft >>= 1;
  223.             *spntr++ = mbottom >>= 1;
  224.             *spntr++ = mright >>= 1;
  225.             }
  226.         HLock(rectStorH);
  227.         for (i = 1; i < (1 << numofDivs); i++) {
  228.             ttopleft = *(long *)startingRect;
  229.             tbotright = ((long *)startingRect)[1];
  230.             lpntr = (long *)*rectStorH;
  231.             tsh = i << ((CHAR_BIT * sizeof(short)) - numofDivs);
  232.             for (j = 1; j <= numofDivs; j++) {
  233.                 if (tsh < 0) {
  234.                     ttopleft += *lpntr++;
  235.                     tbotright += *lpntr++;
  236.                     }
  237.                 else
  238.                     lpntr += 2;
  239.                 tsh <<= 1;
  240.                 }
  241.             
  242.             *(long *)&tempRect = ttopleft;
  243.             ((long *)&tempRect)[1] = tbotright;
  244.             FrameRect(&tempRect);
  245.             FrameRect(&trailingRect);
  246.             trailingRect = tempRect;
  247.             }
  248.         FrameRect(&tempRect);
  249.         DisposHandle(rectStorH);
  250.         SetPenState(&curPen);
  251.         }
  252.     }
  253. }
  254.  
  255. void ZoomRectToRectAutoGrafPort(RectPtr startingRect, RectPtr endingRect, short numofDivs)
  256. {
  257. GrafPtr        savePort;
  258. GrafPort    ZoomPort;
  259.  
  260. GetPort(&savePort);
  261. OpenPort(&ZoomPort);
  262. ZoomRectToRect(startingRect, endingRect, numofDivs);
  263. ClosePort(&ZoomPort);
  264. SetPort(savePort);
  265. }
  266.  
  267. /* NewHandleGeneral: makes a new handle in main or temporary memory, arguably
  268. in the more suitable heap zone */
  269.  
  270. Handle NewHandleGeneral(Size blockSize)
  271. {
  272. register Handle    myH;
  273. OSErr    err;
  274.  
  275. if (TempFreeMem() > FreeMem()) {
  276.     if ((myH = TempNewHandle(blockSize, &err)) == nil) {
  277.         ResrvMem(blockSize);
  278.         myH = NewHandle(blockSize);
  279.         }
  280.     }
  281. else {
  282.     ResrvMem(blockSize);
  283.     if ((myH = NewHandle(blockSize)) == nil)
  284.         myH = TempNewHandle(blockSize, &err);
  285.     }
  286. return(myH);
  287. }
  288.  
  289. /* Get1ResGeneral: like Get1Resource, but loads in main or temporary memory */
  290.  
  291. Handle Get1ResGeneral(ResType theType,short theID)
  292. {
  293. register Handle    emptyH, destH;
  294. register Size    myResSize;
  295.  
  296. SetResLoad(false);
  297. emptyH = Get1Resource(theType, theID);
  298. SetResLoad(true);
  299. destH = NewHandleGeneral(myResSize = SizeResource(emptyH));
  300. if (destH) {
  301.     HLock(destH);
  302.     ReadPartialResource(emptyH, 0L, *destH, myResSize);
  303.     HUnlock(destH);
  304.     }
  305. ReleaseResource(emptyH);
  306. return(destH);
  307. }
  308.  
  309. OSType FindFinderAtEaseProcess(ProcessSerialNumber *theProcess)
  310. {
  311. ProcessInfoRec infoRec;
  312. ProcessSerialNumber process = {0L, kNoProcess};
  313. register OSType    retVal = '????';
  314.  
  315. infoRec.processInfoLength = sizeof(ProcessInfoRec);
  316. infoRec.processName = nil;
  317. infoRec.processAppSpec = nil;
  318.  
  319. while (GetNextProcess(&process) == noErr) {
  320.     if (noErr == (GetProcessInformation(&process, &infoRec))) {
  321.         if ((infoRec.processType == (unsigned long)'FNDR') &&
  322.             ((infoRec.processSignature == 'MACS') || (infoRec.processSignature == 'mfdr'))) {
  323.             
  324.             retVal = infoRec.processSignature;
  325.             *theProcess = process;
  326.             break;
  327.             }
  328.         }
  329.     }
  330. return retVal;
  331. }
  332.  
  333. OSType FindFinderProcess(void)
  334. {
  335. ProcessInfoRec infoRec;
  336. ProcessSerialNumber process = {0, kNoProcess};
  337. register OSType    retVal = '????';
  338.  
  339. infoRec.processInfoLength = sizeof(ProcessInfoRec);
  340. infoRec.processName = nil;
  341. infoRec.processAppSpec = nil;
  342.  
  343. while (GetNextProcess(&process) == noErr) {
  344.     if (noErr == (GetProcessInformation(&process, &infoRec))) {
  345.         if ((infoRec.processType == (unsigned long)'FNDR') &&
  346.             (infoRec.processSignature == 'MACS')) {
  347.             
  348.             retVal = infoRec.processSignature;
  349.             break;
  350.             }
  351.         }
  352.     }
  353. return retVal;
  354. }
  355.  
  356. /* SendShutdownToFinder: we tell the Finder (or At Ease) to Shutdown (!) */
  357.  
  358. OSErr SendShutdownToFinder(AEIdleProcPtr myIdleFunct, Boolean wantShutDown)
  359. {
  360. AEIdleUPP    myIdleFunctUPP = NewAEIdleProc(myIdleFunct);
  361. AppleEvent    myAEvent;
  362. AppleEvent    myAEReply;
  363. ProcessSerialNumber    process;
  364. AEAddressDesc    targetAddress;
  365. OSType    WantedCreator;
  366. register OSErr    err = errAEDescNotFound;
  367.  
  368. WantedCreator = FindFinderAtEaseProcess(&process);
  369. if ('????' != WantedCreator)
  370.     if ((err = AECreateDesc(typeApplSignature, (Ptr)&WantedCreator, sizeof(OSType),
  371.         &targetAddress)) == noErr) {
  372.         if ((err = AECreateAppleEvent(kAEFinderEvents, wantShutDown ? kAEShutDown : kAERestart , &targetAddress,
  373.             kAutoGenerateReturnID, kAnyTransactionID, &myAEvent)) == noErr) {
  374.             err = AESend(&myAEvent, &myAEReply, kAENoReply | kAEAlwaysInteract,
  375.                 kAENormalPriority, kNoTimeOut, myIdleFunctUPP, nil);
  376.             (void)AEDisposeDesc(&myAEvent);
  377.             if (err == noErr)
  378.                 (void)SetFrontProcess(&process);
  379.             }
  380.         (void)AEDisposeDesc(&targetAddress);
  381.         }
  382. if (myIdleFunctUPP)
  383.     DisposeRoutineDescriptor(myIdleFunctUPP);
  384. return err;
  385. }
  386.  
  387. short StopAlert_UPP(short alertID, ModalFilterProcPtr filterProc)
  388. {
  389. ModalFilterUPP    filterProcUPP = NewModalFilterProc(filterProc);
  390. register short    butHit;
  391.  
  392. InitCursor();
  393. butHit = StopAlert(alertID, filterProcUPP);
  394. if (filterProcUPP)
  395.     DisposeRoutineDescriptor(filterProcUPP);
  396. return butHit;
  397. }
  398.  
  399. short StopAlert_AE(short alertID, ModalFilterProcPtr filterProc, AEIdleProcPtr IdleFunct)
  400. {
  401.  
  402. SendmyAE(kCreat, kAEAlert, IdleFunct, kAENoReply | kAEAlwaysInteract);
  403. return StopAlert_UPP(alertID, filterProc);
  404. }
  405.  
  406. short CautionAlert_UPP(short alertID, ModalFilterProcPtr filterProc)
  407. {
  408. ModalFilterUPP    filterProcUPP = NewModalFilterProc(filterProc);
  409. register short    butHit;
  410.  
  411. InitCursor();
  412. butHit = CautionAlert(alertID, filterProcUPP);
  413. if (filterProcUPP)
  414.     DisposeRoutineDescriptor(filterProcUPP);
  415. return butHit;
  416. }
  417.  
  418. short CautionAlert_AE(short alertID, ModalFilterProcPtr filterProc, AEIdleProcPtr IdleFunct)
  419. {
  420.  
  421. SendmyAE(kCreat, kAEAlert, IdleFunct, kAENoReply | kAEAlwaysInteract);
  422. return CautionAlert_UPP(alertID, filterProc);
  423. }
  424.  
  425. short NoteAlert_UPP(short alertID, ModalFilterProcPtr filterProc)
  426. {
  427. ModalFilterUPP    filterProcUPP = NewModalFilterProc(filterProc);
  428. register short    butHit;
  429.  
  430. InitCursor();
  431. butHit = NoteAlert(alertID, filterProcUPP);
  432. if (filterProcUPP)
  433.     DisposeRoutineDescriptor(filterProcUPP);
  434. return butHit;
  435. }
  436.  
  437. short NoteAlert_AE(short alertID, ModalFilterProcPtr filterProc, AEIdleProcPtr IdleFunct)
  438. {
  439.  
  440. SendmyAE(kCreat, kAEAlert, IdleFunct, kAENoReply | kAEAlwaysInteract);
  441. return NoteAlert_UPP(alertID, filterProc);
  442. }
  443.  
  444. short Alert_UPP(short alertID, ModalFilterProcPtr filterProc)
  445. {
  446. ModalFilterUPP    filterProcUPP = NewModalFilterProc(filterProc);
  447. register short    butHit;
  448.  
  449. InitCursor();
  450. butHit = Alert(alertID, filterProcUPP);
  451. if (filterProcUPP)
  452.     DisposeRoutineDescriptor(filterProcUPP);
  453. return butHit;
  454. }
  455.  
  456. short Alert_AE(short alertID, ModalFilterProcPtr filterProc, AEIdleProcPtr IdleFunct)
  457. {
  458.  
  459. SendmyAE(kCreat, kAEAlert, IdleFunct, kAENoReply | kAEAlwaysInteract);
  460. return Alert_UPP(alertID, filterProc);
  461. }
  462.  
  463. /* my Dialog box manager */
  464.  
  465. void FlashButton(DialogPtr dlg, short item)
  466. {
  467. Rect    txtBox;
  468. ControlHandle    itH;
  469. long    dummy;
  470. short    typ;
  471.  
  472. GetDItem(dlg, item, &typ, (Handle *)&itH, &txtBox);
  473. HiliteControl(itH, 1);
  474. Delay(4L, &dummy);
  475. HiliteControl(itH, 0);
  476. }
  477.  
  478. void OutlineButton(DialogPtr oftheDialog, short myItem)
  479. {
  480. enum {
  481. kButtonFrameSize = 3,    /* button frameUs pen size */
  482. kButtonFrameInset = -4    /* inset rectangle adjustment around button */
  483. };
  484.  
  485. PenState    curPen;
  486. GrafPtr    savePort;
  487. Rect    txtBox;
  488. Handle    itH;
  489. short    typ;
  490.  
  491. GetPort(&savePort);
  492. SetPort(oftheDialog);
  493. GetDItem(oftheDialog, myItem, &typ, &itH, &txtBox);
  494. GetPenState(&curPen);
  495. PenNormal();
  496. InsetRect(&txtBox, kButtonFrameInset, kButtonFrameInset);
  497. typ = ((txtBox.bottom - txtBox.top) >> 1) + 2;
  498. PenPat((*(ControlHandle)itH)->contrlHilite == 0 ? &qd.black : &qd.gray);
  499. PenSize(kButtonFrameSize, kButtonFrameSize);
  500. FrameRoundRect(&txtBox, typ, typ);
  501. SetPenState(&curPen);
  502. SetPort(savePort);
  503. }
  504.  
  505. short HandleDialog(ModalFilterProcPtr filterProc,
  506.                     dialogItemsPtr things,
  507.                     void (*initProc)(DialogPtr),
  508.                     void (*userProc)(DialogPtr, Handle, short),
  509.                     short resId)
  510. {
  511. ModalFilterUPP    filterProcUPP = NewModalFilterProc(filterProc);
  512. Rect    box;
  513. Handle    item;
  514. GrafPtr    port;
  515. register long    myRefCon;
  516. register DialogPtr    dPtr;
  517. register dialogItemsPtr    spanPtr;
  518. dialogItemsPtr    itemToBeActivated;
  519. short    type, theItemHit = memFullErr;
  520. short    theGroup, lastItemClosingDialog = cancel;
  521. register short    theType, iNum;
  522. register Boolean    editTextExists = false;
  523. Boolean    dialoging;
  524. #if !defined(FabSystem7orlater)
  525. long    Gresp;
  526. Boolean    dialogManager7Present = false;
  527. #endif
  528.  
  529. InitCursor();
  530. dPtr = GetNewDialog(resId, nil, (DialogPtr)-1L);
  531. if (dPtr) {
  532.     GetPort(&port);
  533.     SetPort(dPtr);
  534.  
  535. #if !defined(FabSystem7orlater)
  536.     if (Gestalt(gestaltDITLExtAttr, &Gresp) == noErr)
  537.         if (Gresp & (1L << gestaltDITLExtPresent))
  538.             dialogManager7Present = true;
  539. #endif
  540.  
  541. #pragma mark Setup
  542.     
  543.     spanPtr = things;
  544.     while (iNum = spanPtr->itemNumber) {
  545.         myRefCon = spanPtr->refCon;
  546.         GetDItem(dPtr, iNum, &type, &item, &box);
  547.         theType = type & itemDisable ? type - itemDisable : type;
  548.         switch(theType) {
  549.             case ctrlItem+btnCtrl:
  550. #if !defined(FabSystem7orlater)
  551.                 if (dialogManager7Present)
  552. #endif
  553.                     {
  554.                     if (myRefCon == 1L)
  555.                         (void) SetDialogDefaultItem(dPtr, iNum);
  556.                     else if (myRefCon == 2L)
  557.                         lastItemClosingDialog = iNum;
  558.                     if (iNum == cancel)
  559.                         (void) SetDialogCancelItem(dPtr, iNum);
  560.                     }
  561.                 break;
  562.             case ctrlItem+chkCtrl:
  563.             case ctrlItem+radCtrl:
  564.                 if (myRefCon > 0) {
  565.                     SetCtlValue((ControlHandle)item, 1);
  566.                     if (userProc)
  567.                         userProc(dPtr, item, iNum);
  568.                     }
  569.                 else if (myRefCon < 0)
  570.                     HiliteControl((ControlHandle)item, 255);
  571.                 break;
  572.             case ctrlItem+resCtrl:
  573.                 if (myRefCon)
  574.                     SetCtlValue((ControlHandle)item, myRefCon);
  575.                 break;
  576.             case statText:
  577.                 if (myRefCon)
  578.                     SetIText(item, (StringPtr)myRefCon);
  579.                 break;
  580.             case editText:
  581.                 SetIText(item, (StringPtr)myRefCon);
  582.                 if(editTextExists == false) {
  583.                     SelIText(dPtr, iNum, 0, 32767);
  584.                     editTextExists = true;
  585.                     }
  586.                 break;
  587.     //        case iconItem:
  588.     //            break;
  589.     //        case picItem:
  590.     //            break;
  591.             case userItem:
  592.                 SetDItem(dPtr, iNum, type, (Handle)myRefCon, &box);
  593.                 break;
  594.             }
  595.         spanPtr++;
  596.         }
  597. #if !defined(FabSystem7orlater)
  598.     if (dialogManager7Present)
  599. #endif
  600.         (void) SetDialogTracksCursor(dPtr, editTextExists);
  601.     if (initProc)
  602.         initProc(dPtr);
  603.     ShowWindow(dPtr);
  604.     
  605. #pragma mark Event Loop
  606.     
  607.     dialoging = true;
  608.     do {
  609.         ModalDialog(filterProcUPP, &theItemHit);
  610.         if (theItemHit) {
  611.             GetDItem(dPtr, theItemHit, &type, &item, &box);
  612.             switch (type) {
  613.                 case ctrlItem+btnCtrl:
  614.                     if ((theItemHit >= ok) && (theItemHit <= lastItemClosingDialog))
  615.                         dialoging = false;
  616.                     else if (userProc)
  617.                         userProc(dPtr, item, theItemHit);
  618.                     break;
  619.                 case ctrlItem+chkCtrl:
  620.                     SetCtlValue((ControlHandle)item, 1 - GetCtlValue((ControlHandle)item));
  621.                     if (userProc)
  622.                         userProc(dPtr, item, theItemHit);
  623.                     break;
  624.                 case ctrlItem+radCtrl:
  625.                     if (GetCtlValue((ControlHandle)item) == 0) {
  626.                         SetCtlValue((ControlHandle)item, 1);
  627.                         for (spanPtr = things; (++spanPtr)->itemNumber != theItemHit; );
  628.                         itemToBeActivated = spanPtr;
  629.                         for (theGroup = spanPtr->group; (--spanPtr)->group == theGroup; );
  630.                         for (; (++spanPtr)->refCon <= 0L; );
  631.                         GetDItem(dPtr, spanPtr->itemNumber, &type, &item, &box);
  632.                         SetCtlValue((ControlHandle)item, 0);
  633.                         spanPtr->refCon = 0L;
  634.                         itemToBeActivated->refCon = 1L;
  635.                         if (userProc)
  636.                             userProc(dPtr, item, theItemHit);
  637.                         }
  638.                     break;
  639.                 case ctrlItem+resCtrl:
  640.                 case editText:
  641.                     if (userProc)
  642.                         userProc(dPtr, item, theItemHit);
  643.                     break;
  644.                 }
  645.             }
  646.         }
  647.     while (dialoging);
  648.     
  649. #pragma mark Return Settings
  650.     
  651.     if (theItemHit == ok) {
  652.         spanPtr = things;
  653.         while (iNum = spanPtr->itemNumber) {
  654.             GetDItem(dPtr, iNum, &type, &item, &box);
  655.             theType = type & itemDisable ? type - itemDisable : type;
  656.             switch(theType) {
  657.                 case ctrlItem+chkCtrl:
  658.                 case ctrlItem+resCtrl:
  659.                     spanPtr->refCon = GetCtlValue((ControlHandle)item);
  660.                     break;
  661.                 case editText:
  662.                     GetIText(item, (StringPtr)spanPtr->refCon);
  663.                     break;
  664.         //        case iconItem:
  665.         //            break;
  666.         //        case picItem:
  667.         //            break;
  668.         //        case userItem:
  669.         //            break;
  670.                 }
  671.             spanPtr++;
  672.             }
  673.         }
  674.     DisposeDialog(dPtr);
  675.     SetPort(port);
  676.     }
  677. else
  678.     SysBeep(1);
  679. if (filterProcUPP)
  680.     DisposeRoutineDescriptor(filterProcUPP);
  681. InitCursor();
  682. return theItemHit;
  683. }
  684.  
  685. /* About box manager */
  686.  
  687. #if    !defined(FabNoSegmentDirectives)
  688. #pragma segment About
  689. #endif
  690.  
  691. /* myAbout: the events directed against the about box are checked with
  692. EventAvail, so that we can discard the about box and process
  693. important events later in the main event loop */
  694.  
  695. void myAbout(void (*theIdleProc)(void),
  696.             UserItemUPP DrawQTPict,
  697.             void (*UpdateProc)(EventRecord *),
  698.             void (*ActivateProc)(EventRecord *)
  699.             )
  700. {
  701. EventRecord    evrec;
  702. DialogPtr    agh, dPtr;
  703. short    iHit;
  704. register Handle    splash;
  705. register Boolean    exit = false;
  706.  
  707. splash = OpenSplash(&agh, DrawQTPict);
  708. if (splash) {
  709.     ShowWindow(agh);
  710.     do {
  711.         SystemTask();
  712.         if (EventAvail(everyEvent, &evrec)) {
  713.             switch(evrec.what) {
  714.                 case mouseDown:
  715.                 case keyDown:
  716.                 case autoKey:
  717.                     exit = true;
  718.                     FlushEvents(mDownMask | mUpMask | keyDownMask | autoKeyMask, 0);
  719.                     break;
  720.                 case mouseUp:
  721.                     (void)GetNextEvent(mUpMask, &evrec);
  722.                     break;
  723.                 case updateEvt :
  724.                     (void)GetNextEvent(updateMask, &evrec);
  725.                     if ((DialogPtr)evrec.message == agh) {
  726.                         BeginUpdate(agh);
  727.                         DrawDialog(agh);
  728.                         EndUpdate(agh);
  729.                         }
  730.                     else
  731.                         if (IsDialogEvent(&evrec))
  732.                             (void) DialogSelect(&evrec, &dPtr, &iHit);
  733.                         else
  734.                             UpdateProc(&evrec);
  735.                     break;
  736.                 case diskEvt :
  737.                 case osEvt :
  738.                 case kHighLevelEvent:
  739.                     exit = true;
  740.                     break;
  741.                 case activateEvt :
  742.                     (void)GetNextEvent(activMask, &evrec);
  743.                     if ((DialogPtr)evrec.message != agh) {
  744.                         if (IsDialogEvent(&evrec))
  745.                             (void) DialogSelect(&evrec, &dPtr, &iHit);
  746.                         else
  747.                             ActivateProc(&evrec);
  748.                         }
  749.                     break;
  750.                 case driverEvt :
  751.                     (void)GetNextEvent(driverMask, &evrec);
  752.                     break;
  753.                 }
  754.             }
  755.         else {
  756.             theIdleProc();
  757.             }
  758.         }
  759.     while (exit == false);
  760.     DisposeSplash(splash, agh);
  761.     }
  762. else
  763.     SysBeep(3);
  764. }
  765.  
  766. /* OpenSplash: puts up the about window */
  767.  
  768. Handle OpenSplash(DialogPtr *pass, UserItemUPP DrawQTPict)
  769. {
  770. enum {
  771. kDLOG_About = 256,
  772. kItemPICT = 1
  773. };
  774.  
  775. Str15    tempS = "\p";
  776. Rect    box;
  777. register DialogPtr    dPtr;
  778. register VersRecHndl    myvers;
  779. register Handle    hand;
  780. Handle    item;
  781. short    type;
  782.  
  783. hand = NewHandle(sizeof(DialogRecord));
  784. if (hand) {
  785.     HLockHi(hand);
  786.     myvers = (VersRecHndl)Get1Resource('vers', 1);
  787.     if (myvers) {
  788.         (void) PLstrncpy(tempS, (*myvers)->shortVersion, 15);
  789.         ReleaseResource((Handle)myvers);
  790.         }
  791.     else
  792.         tempS[0] = 0;
  793.     ParamText((ConstStr255Param)&tempS, nil, nil, nil);
  794.     *pass = dPtr = GetNewDialog(kDLOG_About, *hand, (DialogPtr)-1L);
  795.     if (dPtr) {
  796.         if (DrawQTPict) {
  797.             GetDItem(dPtr, kItemPICT, &type, &item, &box);
  798.             SetDItem(dPtr, kItemPICT, type, (Handle)DrawQTPict, &box);
  799.             }
  800.         }
  801.     else {
  802.         DisposHandle(hand);
  803.         hand = nil;
  804.         }
  805.     }
  806. return(hand);
  807. }
  808.  
  809. /* DisposeSplash: gets rid of the about window */
  810.  
  811. void DisposeSplash(Handle dialog, DialogPtr pass)
  812. {
  813. CloseDialog(pass);
  814. DisposHandle(dialog);
  815. }
  816.  
  817. #if    !defined(FabNoSegmentDirectives)
  818. #pragma segment __%Main
  819. #endif
  820.  
  821. #if defined(powerc) || defined (__powerc)
  822. SignedByte WantThisHandleSafe(Handle myH)
  823. {
  824. SignedByte    cMemTags;
  825.  
  826. cMemTags = HGetState(myH);
  827. HLockHi(myH);
  828. return cMemTags;
  829. }
  830.  
  831. #endif
  832.  
  833.  
  834. /* GetFontNumber: gets font number from font name */
  835.  
  836. Boolean GetFontNumber(ConstStr255Param fontName, short *fontNum)
  837. {
  838. Str255    systemFontName;
  839. register Boolean    retFlag;
  840.  
  841. GetFNum(fontName, fontNum);
  842. if ((retFlag = (*fontNum != 0)) == false) {
  843.     GetFontName(0, systemFontName);
  844.     retFlag = EqualString(fontName, systemFontName, false, false);
  845.     }
  846. return retFlag;
  847. }
  848.  
  849. /*
  850. ** From: dickie@schaefer.math.wisc.edu (Garth Dickie)
  851. ** Newsgroups: comp.sys.mac.programmer
  852. ** Subject: Re: HOW do I get the finder to update its file information..
  853. ** Message-ID: <1992May22.014427.9977@schaefer.math.wisc.edu>
  854. ** Date: 22 May 92 01:44:27 GMT
  855. ** References: <1992May21.231246.23090@crash.cts.com>
  856. ** Organization: Univ. of Wisconsin Dept. of Mathematics
  857. ** Lines: 58
  858. ** 
  859. ** You need to change the modification date of the parent directory.
  860. ** The routine TickleParent below works for me.  In case you are not
  861. ** using the FSSpec structure, the routine MakeWDSpec will convert
  862. ** a working directory / filename pair to a pseudo-FSSpec.  I use
  863. ** this when the new file manager calls are not available, as the rest
  864. ** of my code passes around FSSpecs.  The code compiles under THINK C
  865. ** 5.0, with the usual headers.
  866. ** 
  867. ** BTW (mild flame) this is simple enough that it's pretty annoying
  868. ** when people don't do it.  Most of the nifty little 'drag-and-drop'
  869. ** utilities that have come around recently forget to do this.  Feel
  870. ** free to use the code below in any way you see fit.
  871. */
  872.  
  873. OSErr TickleParent( FSSpec *child )
  874. {
  875. CInfoPBRec    pb;
  876. OSErr         err;
  877.  
  878. pb.dirInfo.ioCompletion = nil;
  879. pb.dirInfo.ioNamePtr = nil;
  880. pb.dirInfo.ioVRefNum = child->vRefNum;
  881. pb.dirInfo.ioFDirIndex = -1;
  882. pb.dirInfo.ioDrDirID = child->parID;
  883.  
  884. err = PBGetCatInfoSync( &pb );
  885.  
  886. if (err == noErr) {
  887.     GetDateTime( &pb.dirInfo.ioDrMdDat );
  888.     pb.dirInfo.ioFDirIndex = 0;
  889. //    pb.dirInfo.ioNamePtr = &child->name;
  890.     pb.dirInfo.ioDrDirID = child->parID;
  891.     err = PBSetCatInfoSync( &pb );
  892.     }
  893.  
  894. return err;
  895. }
  896.  
  897. /* this is taken from "Macintosh Programming Secrets"
  898. by Scott Knaster & Keith Rollin;
  899. optimization by Fabrizio Oddone */
  900.  
  901. Boolean CmdPeriod(EventRecord *theEvent)
  902. {
  903. #define    kModifiersMask    (0xFF00 & ~cmdKey)
  904.  
  905. Handle    hKCHR;
  906. long    /*virtualKey, */keyInfo, state, keyCID;
  907. short    keyCode;
  908. Boolean    result = false;
  909.  
  910. if ((theEvent->what == keyDown) || (theEvent->what == autoKey)) {
  911.     if (theEvent->modifiers & cmdKey) {
  912. //        virtualKey = (theEvent->message >> 8) >> 8;
  913.         keyCode = (theEvent->modifiers & kModifiersMask) | ((unsigned short)theEvent->message >> 8);
  914.         state = 0;
  915.         keyCID = GetScript(GetEnvirons(smKeyScript), smScriptKeys);
  916.         hKCHR = GetResource('KCHR', keyCID);
  917.         if (hKCHR) {
  918.             keyInfo = KeyTrans(*hKCHR, keyCode, &state);
  919.             ReleaseResource(hKCHR);
  920.             }
  921.         else
  922.             keyInfo = theEvent->message;
  923.         
  924.         if (((char)keyInfo == '.') || ((char)(keyInfo >> 16) == '.'))
  925.             result = true;
  926.         }
  927.     }
  928.  
  929. return result;
  930. }
  931.  
  932. /* other useful stuff to detect keypresses */
  933.  
  934. Boolean CmdPeriodOrEsc(EventRecord *theEvent)
  935. {
  936. return ((unsigned short)theEvent->message == kEscapeKey) || CmdPeriod(theEvent);
  937. }
  938.  
  939. Boolean CmdPeriodOrEscConfirm(EventRecord *theEvent, short alertID, ModalFilterProcPtr filterProc)
  940. {
  941. register Boolean    retflag;
  942.  
  943. retflag = CmdPeriodOrEsc(theEvent);
  944. if (retflag) {
  945.     ModalFilterUPP    filterProcUPP = NewModalFilterProc(filterProc);
  946.     
  947.     InitCursor();
  948.     retflag = CautionAlert(alertID, filterProcUPP) == cancel;
  949.     if (filterProcUPP)
  950.         DisposeRoutineDescriptor(filterProcUPP);
  951.     }
  952.  
  953. return retflag;
  954. }
  955.  
  956. #if    !defined(FabNoSegmentDirectives)
  957. #pragma segment Registration
  958. #endif
  959.  
  960. short gHowManyDollars;
  961.  
  962. void HandleRegistration(ModalFilterProcPtr filterProc,
  963.                         long (*regCfgInfo)(Handle, long, StringPtr),
  964.                         short howManyDollars)
  965. {
  966. enum {
  967. kNumStrings = 13,
  968. kMyRegText = 256
  969. };
  970.  
  971. StringPtr    regInfo[kNumStrings];
  972. StdFileResult    theChosenFile;
  973. ParamBlockRec    myPB;
  974. EventRecord    dummyEv;
  975. Str63    tempS = "\p";
  976. long    gResp;
  977. short    tmpFRefN;
  978. const short    zero = 0x0130;
  979. const short    dash = 0x012D;
  980. const char    optspace = 'Δ';
  981. Handle    regText;
  982. VersRecHndl    myvers;
  983. StringHandle    sh;
  984. StringPtr    myAppName = nil;
  985. long    lOffset;
  986. short    i;
  987. OSErr    err;
  988. SignedByte    savedState;
  989.  
  990. dialogItems    things[] = {{ ok, 0, 0L },
  991.                         { cancel, 0, 0L },
  992.                         { kItemUserName, 0, 0L },
  993.                         { kItemCompany, 0, 0L },
  994.                         { kItemAddress, 0, 0L },
  995.                         { kItemCity, 0, 0L },
  996.                         { kItemState, 0, 0L },
  997.                         { kItemZIP, 0, 0L },
  998.                         { kItemCountry, 0, 0L },
  999.                         { kItemE_mail, 0, 0L },
  1000.                         { kItemPhone, 0, 0L },
  1001.                         { kItemFAX, 0, 0L },
  1002.                         { kItemQuantity, 0, 0L },
  1003.                         { kItemCopyFrom, 0, 0L },
  1004.                         { kItemComments, 0, 0L },
  1005.                         { 0, 0, 0L}
  1006.                         };
  1007.  
  1008. lOffset = (long)NewPtrClear(kNumStrings * sizeof(Str255));
  1009. if (lOffset) {
  1010.     things[kItemUserName-1].refCon = lOffset;
  1011.     regInfo[0] = (StringPtr)lOffset;
  1012.     lOffset += (kNumStrings - 1) * sizeof(Str255);
  1013.     for (i = kItemComments - 1; i >= kItemCompany - 1; i--, lOffset -= sizeof(Str255)) {
  1014.         things[i].refCon = lOffset;
  1015.         regInfo[i-2] = (StringPtr)lOffset;
  1016.         }
  1017.     
  1018.     (void)PLstrcpy((StringPtr)things[kItemQuantity-1].refCon, "\p2");
  1019.     
  1020.     gHowManyDollars = howManyDollars;
  1021.     sh = GetString(kSTR_ApplicationName);
  1022.     if (sh) {
  1023.         savedState = WantThisHandleSafe((Handle)sh);
  1024.         myAppName = *sh;
  1025.         }
  1026.     
  1027.     ParamText(myAppName, (ConstStr255Param)&zero, (ConstStr255Param)&zero, nil);
  1028.     if (sh)
  1029.         HSetState((Handle)sh, savedState);
  1030.     do
  1031.         if (HandleDialog(filterProc, (dialogItemsPtr)&things, RegInitProc, nil, kDLOG_Register) == ok)
  1032.             do {
  1033.                 if ((err = AskForDestFile(&theChosenFile, nil, nil)) == dupFNErr) {
  1034.                     InitCursor();
  1035.                     (void)StopAlert(kALRT_REGCANNOTREPLACE, nil);
  1036.                     }
  1037.                 }
  1038.             while (err == dupFNErr);
  1039.         else
  1040.             err = dupFNErr;
  1041.     while (err == userCanceledErr);
  1042.     if (err == noErr) {
  1043.         regText = Get1Resource('TEXT', kMyRegText);
  1044.         if (regText) {
  1045.             DetachResource(regText);
  1046.             myvers = (VersRecHndl)Get1Resource('vers', 1);
  1047.             if (myvers) {
  1048.                 (void) PLstrcpy(tempS, (*myvers)->shortVersion);
  1049.                 ReleaseResource((Handle)myvers);
  1050.                 }
  1051.             lOffset = Munger(regText, 0L, &optspace, 1L, &tempS[1], tempS[0]);
  1052.             for (i = kItemUserName-3; i <= kItemFAX-3; i++)
  1053.                 lOffset = Munger(regText, lOffset, &optspace, 1L, ®Info[i][1], regInfo[i][0]);
  1054.             for (i = kItemCopyFrom-3; i <= kItemComments-3; i++)
  1055.                 lOffset = Munger(regText, lOffset, &optspace, 1L, ®Info[i][1], regInfo[i][0]);
  1056.             
  1057.             /* Mac model */
  1058.             if (Gestalt(gestaltMachineType, &gResp) == noErr) {
  1059.                 myAppName = GetPtrIndHString(GetResource('STR#', kMachineNameStrID), (unsigned short)(gResp - 1L));
  1060.                 lOffset = Munger(regText, lOffset, &optspace, 1L, &myAppName[1], myAppName[0]);
  1061.                 }
  1062.             else {
  1063.                 lOffset = Munger(regText, lOffset, &optspace, 1L, &((char *)&dash)[1], 1L);
  1064.                 }
  1065.             /* Sys version */
  1066.             if (Gestalt(gestaltSystemVersion, &gResp) == noErr) {
  1067.                 BCDVersNumToString(gResp, tempS);
  1068.                 }
  1069.             else {
  1070.                 *(short *)tempS = dash;
  1071.                 }
  1072.             lOffset = Munger(regText, lOffset, &optspace, 1L, &tempS[1], tempS[0]);
  1073.             /* addr mode info */
  1074.             if (Gestalt(gestaltAddressingModeAttr, &gResp) == noErr) {
  1075.                 MyNumToString(gResp, tempS);
  1076.                 }
  1077.             else {
  1078.                 *(short *)tempS = dash;
  1079.                 }
  1080.             lOffset = Munger(regText, lOffset, &optspace, 1L, &tempS[1], tempS[0]);
  1081.             /* A/UX info */
  1082.             if (Gestalt(gestaltAUXVersion, &gResp) == noErr) {
  1083.                 BCDVersNumToString(gResp, tempS);
  1084.                 }
  1085.             else {
  1086.                 *(short *)tempS = dash;
  1087.                 }
  1088.             lOffset = Munger(regText, lOffset, &optspace, 1L, &tempS[1], tempS[0]);
  1089.             /* Hardware info */
  1090.             if (Gestalt(gestaltHardwareAttr, &gResp) == noErr) {
  1091.                 MyNumToString(gResp, tempS);
  1092.                 }
  1093.             else {
  1094.                 *(short *)tempS = dash;
  1095.                 }
  1096.             lOffset = Munger(regText, lOffset, &optspace, 1L, &tempS[1], tempS[0]);
  1097.             /* VM info */
  1098.             if (Gestalt(gestaltVMAttr, &gResp) == noErr) {
  1099.                 MyNumToString(gResp, tempS);
  1100.                 }
  1101.             else {
  1102.                 *(short *)tempS = dash;
  1103.                 }
  1104.             lOffset = Munger(regText, lOffset, &optspace, 1L, &tempS[1], tempS[0]);
  1105.             /* Power Manager info */
  1106.             if (Gestalt(gestaltPowerMgrAttr, &gResp) == noErr) {
  1107.                 MyNumToString(gResp, tempS);
  1108.                 }
  1109.             else {
  1110.                 *(short *)tempS = dash;
  1111.                 }
  1112.             lOffset = Munger(regText, lOffset, &optspace, 1L, &tempS[1], tempS[0]);
  1113.             /* Processor type info */
  1114.             if (Gestalt(gestaltProcessorType, &gResp) == noErr) {
  1115.                 MyNumToString(gResp, tempS);
  1116.                 }
  1117.             else {
  1118.                 *(short *)tempS = dash;
  1119.                 }
  1120.             lOffset = Munger(regText, lOffset, &optspace, 1L, &tempS[1], tempS[0]);
  1121.             /* System architecture info */
  1122.             if (Gestalt('sysa', &gResp) == noErr) {
  1123.                 MyNumToString(gResp, tempS);
  1124.                 }
  1125.             else {
  1126.                 *(short *)tempS = dash;
  1127.                 }
  1128.             lOffset = Munger(regText, lOffset, &optspace, 1L, &tempS[1], tempS[0]);
  1129.             /* Native processor info */
  1130.             if (Gestalt('cput', &gResp) == noErr) {
  1131.                 MyNumToString(gResp, tempS);
  1132.                 }
  1133.             else {
  1134.                 *(short *)tempS = dash;
  1135.                 }
  1136.             lOffset = Munger(regText, lOffset, &optspace, 1L, &tempS[1], tempS[0]);
  1137.             /* System 7 tuner info */
  1138.             if (Gestalt('bugz', &gResp) == noErr) {
  1139.                 MyNumToString(gResp, tempS);
  1140.                 }
  1141.             else {
  1142.                 *(short *)tempS = dash;
  1143.                 }
  1144.             lOffset = Munger(regText, lOffset, &optspace, 1L, &tempS[1], tempS[0]);
  1145.             /* Hardware System Updater info */
  1146.             if (Gestalt('bugy', &gResp) == noErr) {
  1147.                 MyNumToString(gResp, tempS);
  1148.                 }
  1149.             else {
  1150.                 *(short *)tempS = dash;
  1151.                 }
  1152.             lOffset = Munger(regText, lOffset, &optspace, 1L, &tempS[1], tempS[0]);
  1153.             /* Hardware System Updater 3 info */
  1154.             if (Gestalt('bugx', &gResp) == noErr) {
  1155.                 MyNumToString(gResp, tempS);
  1156.                 }
  1157.             else {
  1158.                 *(short *)tempS = dash;
  1159.                 }
  1160.             lOffset = Munger(regText, lOffset, &optspace, 1L, &tempS[1], tempS[0]);
  1161.             /* AppleScript info */
  1162.             if (Gestalt('ascv', &gResp) == noErr) {
  1163.                 BCDLongVersNumToString(gResp, tempS);
  1164.                 }
  1165.             else {
  1166.                 *(short *)tempS = dash;
  1167.                 }
  1168.             lOffset = Munger(regText, lOffset, &optspace, 1L, &tempS[1], tempS[0]);
  1169.             /* QuickTime info */
  1170.             if (Gestalt('qtim', &gResp) == noErr) {
  1171.                 BCDLongVersNumToString(gResp, tempS);
  1172.                 }
  1173.             else {
  1174.                 *(short *)tempS = dash;
  1175.                 }
  1176.             lOffset = Munger(regText, lOffset, &optspace, 1L, &tempS[1], tempS[0]);
  1177.             /* Thread Manager info */
  1178.             if (Gestalt(gestaltThreadMgrAttr, &gResp) == noErr) {
  1179.                 MyNumToString(gResp, tempS);
  1180.                 }
  1181.             else {
  1182.                 *(short *)tempS = dash;
  1183.                 }
  1184.             lOffset = Munger(regText, lOffset, &optspace, 1L, &tempS[1], tempS[0]);
  1185.             /* custom configuration */
  1186.             if (regCfgInfo)
  1187.                 lOffset = regCfgInfo(regText, lOffset, tempS);
  1188.             
  1189.             /* quantity */
  1190.             lOffset = Munger(regText, lOffset, &optspace, 1L, ®Info[kItemQuantity-3][1], regInfo[kItemQuantity-3][0]);
  1191.             StringToNum(regInfo[kItemQuantity-3], &gResp);
  1192.             MyNumToString(howManyDollars * sqrt(gResp), tempS);
  1193.     //        UnloadSeg(sqrt);
  1194.             lOffset = Munger(regText, lOffset, &optspace, 1L, &tempS[1], tempS[0]);
  1195.             IUDateString(LMGetTime(), longDate, tempS);
  1196.             lOffset = Munger(regText, lOffset, &optspace, 1L, &tempS[1], tempS[0]);
  1197. // 6
  1198.             if ((err = FabFSpCreate(&theChosenFile.destFile, 'ttxt', 'TEXT', theChosenFile.theScript)) == noErr) {
  1199.                 if ((err = FabFSpOpenDF(&theChosenFile.destFile, fsWrPerm, &tmpFRefN)) == noErr) {
  1200. // 6
  1201.                     HLockHi(regText);
  1202.                     myPB.ioParam.ioCompletion = nil;
  1203.                     myPB.ioParam.ioBuffer = *regText;
  1204.                     myPB.ioParam.ioReqCount = InlineGetHandleSize(regText);
  1205.                     myPB.ioParam.ioPosMode = fsFromStart;
  1206.                     myPB.ioParam.ioRefNum = tmpFRefN;
  1207.                     myPB.ioParam.ioPosOffset = 0L;
  1208.                     (void)PBWriteAsync(&myPB);
  1209.                     while (myPB.ioParam.ioResult > 0) {
  1210.                         SystemTask();
  1211.                         (void)EventAvail(everyEvent, &dummyEv);
  1212.                         }
  1213.                     HUnlock(regText);
  1214.                     (void)FSClose(tmpFRefN);
  1215.                     InitCursor();
  1216.                     MyNumToString(myPB.ioParam.ioResult, tempS);
  1217.                     ParamText(theChosenFile.destFile.name, tempS, nil, nil);
  1218.                     if (myPB.ioParam.ioResult == noErr) {
  1219.                         (void) NoteAlert(kALRT_REGSUCCESSSAVED, nil);
  1220.                         }
  1221.                     else if (myPB.ioParam.ioResult == dskFulErr) {
  1222. // 6
  1223.                         (void) FabFSpDelete(&theChosenFile.destFile);
  1224. // 6
  1225.                         (void) StopAlert(kALRT_REGDISKFULL, nil);
  1226.                         }
  1227.                     else
  1228.                         (void) StopAlert(kALRT_REGUNKNOWNWRITEERROR, nil);
  1229.                     }
  1230.                 else
  1231.                     (void) StopAlert(kALRT_REGCOULDNOTOPENFORWRITING, nil);
  1232.                 }
  1233.             else
  1234.                 (void) StopAlert(kALRT_REGCOULDNOTCREATE, nil);
  1235.             DisposHandle(regText);
  1236.             }
  1237.         }
  1238.     DisposPtr((Ptr)regInfo[0]);
  1239.     }
  1240. else
  1241.     SysBeep(2);
  1242. }
  1243.  
  1244. void RegInitProc(DialogPtr myDPtr)
  1245. {
  1246. Str255    textStr, discountStr;
  1247. Rect    iRect;
  1248. Handle    iHandle;
  1249. long    qty;
  1250. short    iType;
  1251. register RgnHandle    updtRgn;
  1252.  
  1253. GetDItem(myDPtr, kItemQuantity, &iType, &iHandle, &iRect);
  1254. GetIText(iHandle, textStr);
  1255. StringToNum(textStr, &qty);
  1256. MyNumToString(gHowManyDollars * qty, textStr);
  1257. MyNumToString(gHowManyDollars * sqrt(qty), discountStr);
  1258. //UnloadSeg(sqrt);
  1259. ParamText(nil, textStr, discountStr, nil);
  1260. GetDItem(myDPtr, kItemTotals, &iType, &iHandle, &iRect);
  1261. updtRgn = NewRgn();
  1262. if (updtRgn) {
  1263.     RectRgn(updtRgn, &iRect);
  1264.     UpdtDialog(myDPtr, updtRgn);
  1265.     DisposeRgn(updtRgn);
  1266.     }
  1267. }
  1268.  
  1269. OSErr AskForDestFile(StdFileResultPtr whichFile, Ptr prompt, Ptr docName)
  1270. {
  1271. enum {
  1272. kSTR_PROMPT = 300,
  1273. kSTR_DEFNAME
  1274. };
  1275.  
  1276. StandardFileReply    mySFR;
  1277. register Handle    sH1;
  1278. register Handle    sH2;
  1279. register SignedByte    state1, state2;
  1280. register OSErr    err = userCanceledErr;
  1281.  
  1282. // 6
  1283. FabStandardPutFile(prompt ? (ConstStr255Param)prompt : (sH1 = (Handle)GetString(kSTR_PROMPT),
  1284.                                         state1 = WantThisHandleSafe(sH1),
  1285.                                         (ConstStr255Param)*sH1),
  1286.                 docName ? (ConstStr255Param)docName : (sH2 = (Handle)GetString(kSTR_DEFNAME),
  1287.                                     state2 = WantThisHandleSafe(sH2),
  1288.                                     (ConstStr255Param)*sH2),
  1289.                 &mySFR);
  1290. // 6
  1291.  
  1292. if (docName == nil)
  1293.     HSetState(sH2, state2);
  1294. if (prompt == nil)
  1295.     HSetState(sH1, state1);
  1296.  
  1297. if (mySFR.sfGood) {
  1298.     if (mySFR.sfReplacing)
  1299.         err = dupFNErr;
  1300.     else {
  1301.         err = noErr;
  1302.         whichFile->destFile = mySFR.sfFile;
  1303.         whichFile->theScript = mySFR.sfScript;
  1304.         if (docName)
  1305.             (void) PLstrncpy((StringPtr)docName, mySFR.sfFile.name, 31);
  1306.         }
  1307.     }
  1308. return err;
  1309. }
  1310.  
  1311. void BCDVersNumToString(long num, StringPtr str)
  1312. {
  1313. Str15    tmpstr;
  1314. const short    onepoint = 0x012E;
  1315. register long    tmp;
  1316.  
  1317. str[0] = 0;
  1318. tmp = num;
  1319. tmp >>= 8;
  1320. tmp &= 0xFF;
  1321. MyNumToString(tmp, str);
  1322. (void) PLstrcat(str, (StringPtr)&onepoint);
  1323. tmp = num;
  1324. tmp >>= 4;
  1325. tmp &= 0xF;
  1326. MyNumToString(tmp, tmpstr);
  1327. (void) PLstrcat(str, (StringPtr)&tmpstr);
  1328. tmp = num;
  1329. tmp &= 0xF;
  1330. if (tmp) {
  1331.     MyNumToString(tmp, tmpstr);
  1332.     (void) PLstrcat(str, (StringPtr)&onepoint);
  1333.     (void) PLstrcat(str, (StringPtr)&tmpstr);
  1334.     }
  1335. }
  1336.  
  1337. void BCDLongVersNumToString(long num, StringPtr str)
  1338. {
  1339. Str15    tmpstr;
  1340. const short    onepoint = 0x012E;
  1341. const short    devStr = 0x0164;
  1342. const short    alphaStr = 0x0161;
  1343. const short    betaStr = 0x0162;
  1344. const short    releaseStr = 0x0172;
  1345. register long    tmp;
  1346.  
  1347. str[0] = 0;
  1348. tmp = num;
  1349. tmp >>= 24;
  1350. tmp &= 0xFF;
  1351. MyNumToString(tmp, str);
  1352. (void) PLstrcat(str, (StringPtr)&onepoint);
  1353. tmp = num;
  1354. tmp >>= 20;
  1355. tmp &= 0xF;
  1356. MyNumToString(tmp, tmpstr);
  1357. (void) PLstrcat(str, (StringPtr)&tmpstr);
  1358. tmp = num;
  1359. tmp >>= 16;
  1360. tmp &= 0xF;
  1361. if (tmp) {
  1362.     MyNumToString(tmp, tmpstr);
  1363.     (void) PLstrcat(str, (StringPtr)&onepoint);
  1364.     (void) PLstrcat(str, (StringPtr)&tmpstr);
  1365.     }
  1366. tmp = num;
  1367. tmp >>= 8;
  1368. tmp &= 0xFF;
  1369. switch (tmp) {
  1370.     case developStage:
  1371.         (void) PLstrcat(str, (StringPtr)&devStr);
  1372.         break;
  1373.     case alphaStage:
  1374.         (void) PLstrcat(str, (StringPtr)&alphaStr);
  1375.         break;
  1376.     case betaStage:
  1377.         (void) PLstrcat(str, (StringPtr)&betaStr);
  1378.         break;
  1379.     case finalStage:
  1380.         (void) PLstrcat(str, (StringPtr)&releaseStr);
  1381.         break;
  1382.     }
  1383. tmp = num;
  1384. tmp &= 0xFF;
  1385. if (tmp) {
  1386.     MyNumToString(tmp, tmpstr);
  1387.     (void) PLstrcat(str, (StringPtr)&tmpstr);
  1388.     }
  1389. }
  1390.  
  1391. #if    !defined(FabNoSegmentDirectives)
  1392. #pragma segment Init
  1393. #endif
  1394.  
  1395. /* Code from Apple® converted by Fabrizio Oddone in super-optimized (!) C */
  1396.  
  1397. /* InitGraf is always implemented (trap $A86E). If the trap table is big
  1398.   enough, trap $AA6E will always point to either Unimplemented or some other
  1399.   trap, but will never be the same as InitGraf. Thus, you can check the size
  1400.   of the trap table by asking if the address of trap $A86E is the same as
  1401.   $AA6E. */
  1402.  
  1403. #define NumToolboxTraps    ((GetToolTrapAddress(_InitGraf) == GetToolTrapAddress(0xAA6E)) ? 0x0200 : 0x0400)
  1404.  
  1405. /* Determines the type of a trap based on its trap number. If bit 11 is clear,
  1406.   then it is an OS trap. Otherwise, it is a Toolbox trap. */
  1407. /* OS traps start with A0, Tool with A8 or AA. */
  1408.  
  1409. #define GetTrapType(which)    (((which) & 0x0800) ? ToolTrap : OSTrap)
  1410.  
  1411. /* Check to see if a given trap is implemented. This is only used by the
  1412.   Initialize routine in this program, so we put it in the Initialize segment.*/
  1413.  
  1414. Boolean TrapAvailable(short theTrap)
  1415. {
  1416. register UniversalProcPtr    theTrapAddress;
  1417. register short    temp;
  1418.  
  1419. temp = theTrap;
  1420. if(GetTrapType(temp) == ToolTrap) {
  1421.     temp &= 0x07FF;
  1422.     if( temp >= NumToolboxTraps)
  1423.         temp = _Unimplemented;
  1424.     theTrapAddress = GetToolTrapAddress(temp);
  1425.     }
  1426. else
  1427.     theTrapAddress = GetOSTrapAddress(temp);
  1428. return( GetToolTrapAddress(_Unimplemented) != theTrapAddress);
  1429. }
  1430.  
  1431. OSErr InstallRequiredAEHandlers(AEEventHandlerProcPtr myOAPP,
  1432.                                 AEEventHandlerProcPtr myODOC,
  1433.                                 AEEventHandlerProcPtr myPDOC,
  1434.                                 AEEventHandlerProcPtr myQUIT)
  1435. {
  1436. OSErr    err;
  1437.  
  1438. gmyOAPP_UPP = NewAEEventHandlerProc(myOAPP);
  1439. gmyODOC_UPP = NewAEEventHandlerProc(myODOC);
  1440. gmyPDOC_UPP = NewAEEventHandlerProc(myPDOC);
  1441. gmyQUIT_UPP = NewAEEventHandlerProc(myQUIT);
  1442. if(noErr == (err = AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, gmyOAPP_UPP, 0, false)))
  1443.     if(noErr == (err = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, gmyODOC_UPP, 0, false)))
  1444.         if(noErr == (err = AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, gmyPDOC_UPP, 0, false)))
  1445.             if(noErr == (err = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, gmyQUIT_UPP, 0, false)))
  1446.                 ;
  1447.  
  1448. return err;
  1449. }
  1450.  
  1451. #endif
  1452.  
  1453.